#include "StdAfx.h"
#include "FuncAddDxfInOut.h"

extern DbxPara g_DbxPara;

FuncAddDxfInOut::FuncAddDxfInOut(void)
{
}

FuncAddDxfInOut::~FuncAddDxfInOut(void)
{
}

void FuncAddDxfInOut::FindFuncDxfInPos()
{
	CString csFunc = _T("Acad::ErrorStatus ") + g_DbxPara.m_csClassName + _T("::dxfInFields");
	PublicFunc::FindPosStringHased(m_csReadlines,csFunc,m_idFuncDxfInStart);
	PublicFunc::FindFunctionTailPos(m_csReadlines,csFunc,m_idFuncDxfInEnd);
}

void FuncAddDxfInOut::FindFuncDxfOutPos()
{
	CString csFunc = _T("Acad::ErrorStatus ") + g_DbxPara.m_csClassName + _T("::dxfOutFields");
	PublicFunc::FindPosStringHased(m_csReadlines,csFunc,m_idFuncDxfOutStart);
	PublicFunc::FindFunctionTailPos(m_csReadlines,csFunc,m_idFuncDxfOutEnd);
}

BOOL FuncAddDxfInOut::FindDxfInInsertPos(int& ipos)
{
	int idhead=0,idtail=0;
	for (int k=m_idFuncDxfInEnd;k>=m_idFuncDxfInStart;k--)
	{
		CString cs = m_csReadlines[k];
		if (PublicFunc::IsStrHasStr(cs,_T("return"),idhead,idtail))
		{
			ipos = k-1;
			return TRUE;
		}
	}

	return FALSE;
}

BOOL FuncAddDxfInOut::FindDxfOutInsertPos(int& ipos)
{
	int idhead=0,idtail=0;
	for (int k=m_idFuncDxfOutEnd;k>=m_idFuncDxfOutStart;k--)
	{
		CString cs = m_csReadlines[k];
		if (PublicFunc::IsStrHasStr(cs,_T("return"),idhead,idtail))
		{
			ipos = k-1;
			return TRUE;
		}
	}

	return FALSE;
}

void FuncAddDxfInOut::main()
{
	CString csType,csName,str,csItem,strdxf,var;
	for (int k=0;k<g_DbxPara.m_csVarList.GetSize();k++)
	{
		CString cs = g_DbxPara.m_csVarList[k];
		PublicFunc::GetVarNameType(cs,csName,csType,str);

		if (PublicFunc::IsVectorType(csType,csItem)) continue;
		if (csType=="AcGeCurve3d*") continue;
		if (csType=="AcDbSoftPointerId") continue;

		PublicFunc::ReadSourceFile(m_csSourceFileFullName,m_csReadlines);
		FindFuncDxfInPos();
		FindFuncDxfOutPos();

		int idInsert=0;
		if (FindDxfInInsertPos(idInsert))
		{
			CString csDxfMax;
			GetMaxDxfStringByType(csType,csDxfMax,TRUE);

			CStringArray csCodes;
			csCodes.Add(_T("	pFiler->readItem (&rb) ;\n"));
			csCodes.Add(_T("	if (rb.restype == ") + csDxfMax + _T(") {\n"));

			GetRbDataToVarString(csType,csName,csCodes);

			csCodes.Add(_T("    } else {\n"));
			csCodes.Add(_T("	    pFiler->pushBackItem () ;\n"));
			csCodes.Add(_T("	    pFiler->setError (Acad::eInvalidDxfCode,\n"));
			csCodes.Add(_T("	    _T(\"nError: expected group code %d\"),\n")) ;
			csCodes.Add(_T("	        ") + csDxfMax + _T(");\n"));
			csCodes.Add(_T("	    return pFiler->filerStatus ();\n"));
			csCodes.Add(_T("    }\n\n"));

			WriteDxfInCode(idInsert,csCodes);
		}
	}

	for (int k=0;k<g_DbxPara.m_csVarList.GetSize();k++)
	{
		CString cs = g_DbxPara.m_csVarList[k];
		PublicFunc::GetVarNameType(cs,csName,csType,str);

		if (PublicFunc::IsVectorType(csType,csItem)) continue;
		if (csType=="AcGeCurve3d*") continue;
		if (csType=="AcDbSoftPointerId") continue;

		PublicFunc::ReadSourceFile(m_csSourceFileFullName,m_csReadlines);
		FindFuncDxfOutPos();

		int idInsert=0;
		if (FindDxfOutInsertPos(idInsert))
		{
			CString csDxfMax;
			GetMaxDxfStringByType(csType,csDxfMax,FALSE);

			CStringArray csCodes;
			csCodes.Add(_T("	pFiler->writeItem(") + csDxfMax + _T(", m_") + csName + _T(");\n"));
			WriteDxfInCode(idInsert,csCodes);
		}
	}
}

void FuncAddDxfInOut::WriteDxfInCode(int idPos,CStringArray& csCodes)
{
	CFileFind finder;

	CString csFile = m_csSourceFileFullName;

	BOOL bResult = finder.FindFile(csFile);
	if (bResult)
	{
		DeleteFile(csFile);
	}

	try 
	{
		CString str;
		CStdioFile file (csFile, CFile::modeCreate|CFile::modeWrite);				file.SetLength(0);

		int num = this->m_csReadlines.GetSize();
		for (int k=0;k<num;k++)
		{
			CString string = m_csReadlines[k];
			if (k==idPos)
			{
				for (int j=0;j<csCodes.GetSize();j++)
				{
					file.WriteString(csCodes[j]);
				}

				file.WriteString (string);
				file.WriteString (_T("\n"));
			}
			else
			{
				file.WriteString (string);
				file.WriteString (_T("\n"));
			}
		}
		file.Close() ;
	}
	catch (CFileException* e) 
	{
		e->ReportError ();
		e->Delete ();

		return ;
	}
}

BOOL FuncAddDxfInOut::GetMaxDxfStringByType(CString csType,CString& dxfstr,BOOL bFindDxfIn)
{
	if (csType=="AcGePoint3d"||csType=="AcGeVector3d")
	{
		if (GetNewDxfStringByString(_T("AcDb::kDxfXCoord"),dxfstr,bFindDxfIn)) return TRUE;
		if (GetNewDxfStringByString(_T("AcDb::kDxfNormalX"),dxfstr,bFindDxfIn)) return TRUE;
	}
	else if (csType==_T("Acad2007_char*"))
	{
		if (GetNewDxfStringByString(_T("AcDb::kDxfText"),dxfstr,bFindDxfIn)) return TRUE;
		if (GetNewDxfStringByString(_T("AcDb::kDxfXTextString"),dxfstr,bFindDxfIn)) return TRUE;
	}
	else if (csType==_T("Adesk::Boolean")||csType==_T("Adesk::Int8"))
	{
		if (GetNewDxfStringByString(_T("AcDb::kDxfInt8"),dxfstr,bFindDxfIn)) return TRUE;
	}
	else if (csType==_T("Adesk::Int16"))
	{
		if (GetNewDxfStringByString(_T("AcDb::kDxfInt16"),dxfstr,bFindDxfIn)) return TRUE;
		if (GetNewDxfStringByString(_T("AcDb::kDxfXInt16"),dxfstr,bFindDxfIn)) return TRUE;
	}
	else if (csType==_T("Adesk::Int32"))
	{
		if (GetNewDxfStringByString(_T("AcDb::kDxfInt32"),dxfstr,bFindDxfIn)) return TRUE;
	}
	else if (csType==_T("double"))
	{
		if (GetNewDxfStringByString(_T("AcDb::kDxfReal"),dxfstr,bFindDxfIn)) return TRUE;
		if (GetNewDxfStringByString(_T("AcDb::kDxfXReal"),dxfstr,bFindDxfIn)) return TRUE;
	}

	return FALSE;
}

void FuncAddDxfInOut::FindMaxDxfInCodeByString(CString csDxf,int& idmax)
{
	idmax=0;
	int idhead,idtail;

	BOOL bFindAdd = FALSE;
	for (int i=m_idFuncDxfInStart;i<=m_idFuncDxfInEnd;i++)
	{
		CString cs = m_csReadlines[i];
		if (PublicFunc::IsStrHasStr(cs,csDxf,idhead,idtail))
		{
			int id1 = cs.Find(_T("+"),idtail);
			int id2 = cs.Find(_T(")"),idtail);
			if (id1!=-1)
			{
				CString csNum = cs.Mid(id1+1,id2-id1);
				int idnew = atoi(csNum);
				if (idmax<idnew)
				{
					idmax = idnew;
				}

				bFindAdd = TRUE;
			}
			else 
			{
				idmax=1;
			}
		}
	}

	if (bFindAdd) idmax++;
}

void FuncAddDxfInOut::FindMaxDxfOutCodeByString(CString csDxf,int& idmax)
{
	idmax=0;
	int idhead,idtail;

	BOOL bFindAdd = FALSE;
	for (int i=m_idFuncDxfOutStart;i<=m_idFuncDxfOutEnd;i++)
	{
		CString cs = m_csReadlines[i];
		if (PublicFunc::IsStrHasStr(cs,csDxf,idhead,idtail))
		{
			int id1 = cs.Find(_T("+"),idtail);
			int id2 = cs.Find(_T(","),idtail);
			if (id1!=-1)
			{
				CString csNum = cs.Mid(id1+1,id2-id1);
				int idnew = atoi(csNum);
				if (idmax<idnew)
				{
					idmax = idnew;
				}

				bFindAdd = TRUE;
			}
			else 
			{
				idmax=1;
			}
		}
	}

	if (bFindAdd) idmax++;
}

BOOL FuncAddDxfInOut::GetNewDxfStringByString(CString csDxf,CString& dxfstr,BOOL bFindDxfIn)
{
	int idmax=0;
	if (bFindDxfIn)
	{
		FindMaxDxfInCodeByString(csDxf,idmax);
	}
	else
	{
		FindMaxDxfOutCodeByString(csDxf,idmax);
	}

	if (idmax==0)
	{
		dxfstr = csDxf;
		return TRUE;
	}
	else if (idmax<20)
	{
		CString csNum;
		csNum.Format(" + %d",idmax);
		dxfstr = csDxf +csNum;
		return TRUE;
	}

	return FALSE;
}

void FuncAddDxfInOut::GetRbDataToVarString(CString csType,CString csName,CStringArray& csCodes)
{
	if (csType=="AcGePoint3d"||csType=="AcGeVector3d")
	{
		csCodes.Add(_T("         m_")+csName+_T(" = asPnt3d(rb.resval.rpoint);\n"));
	}
	else if (csType==_T("Acad2007_char*"))
	{
		csCodes.Add(_T("         Acad2007_free(m_")+csName+_T(");\n"));
		csCodes.Add(_T("         m_")+csName+_T(" = Acad2007_strdup(rb.resval.rstring);\n"));
	}
	else if (csType==_T("Adesk::Boolean")||csType==_T("Adesk::Int8")||csType==_T("Adesk::Int16"))
	{
		csCodes.Add(_T("         m_")+csName+_T(" = rb.resval.rint;\n"));
	}
	else if (csType==_T("Adesk::Int32"))
	{
		csCodes.Add(_T("         m_")+csName+_T(" = rb.resval.rlong;\n"));
	}
	else if (csType==_T("double"))
	{
		csCodes.Add(_T("         m_")+csName+_T(" = rb.resval.rreal;\n"));
	}
}
